[Hadoop] 分布式文件系统HDFS 二

HDFS环境搭建、常见问题(小文件问题、Namenode内存管理、数据迁移、数据平衡)、数据压缩、纠删码

Posted by 李玉坤 on 2017-05-31

HDFS环境搭建

官网安装文档
Hadoop伪分布式安装步骤
http://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/SingleCluster.html

下载Hadoop
http://archive.cloudera.com/cdh5/cdh/5/
2.6.0-cdh5.7.0
或则 wget http://archive.cloudera.com/cdh5/cdh/5/hadoop-2.6.0-cdh5.7.0.tar.gz

前置条件:记得检查hostname和配置host映射

  1. jdk安装

    1
    2
    3
    4
    5
    6
    解压:tar -zxvf jdk-7u79-linux-x64.tar.gz -C ~/app
    添加到系统环境变量: ~/.bash_profile
    export JAVA_HOME=/home/hadoop/app/jdk1.7.0_79
    export PATH=\$JAVA_HOME/bin:$PATH
    使得环境变量生效: source ~/.bash_profile
    验证java是否配置成功: java -v
  2. 安装ssh

    1
    2
    3
    sudo yum install ssh
    ssh-keygen -t rsa
    cp ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
  3. 下载并解压hadoop

    1
    2
    下载:直接去cdh网站下载
    解压:tar -zxvf hadoop-2.6.0-cdh5.7.0.tar.gz -C ~/app
  4. hadoop配置文件的修改(hadoop_home/etc/hadoop)
    hadoop-env.sh

    1
    2
    3
    4
    5
    export JAVA_HOME=/home/hadoop/app/jdk1.7.0_79

    # mkdir /home/hadoop/tmp
    # chmod -R 777 /home/hadoop/tmp
    export HADOOP_PID_DIR=/home/hadoop/tmp

core-site.xml

1
2
3
4
5
6
7
8
9
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop000:8020</value>
</property>

<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/app/tmp</value>
</property>

hdfs-site.xml

1
2
3
4
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
  1. 启动hdfs
    格式化文件系统(仅第一次执行即可,不要重复执行):hdfs/hadoop namenode -format
    启动hdfs: sbin/start-dfs.sh
    验证是否启动成功:

    jps

     DataNode

     SecondaryNameNode
     NameNode
    浏览器访问方式 http://hadoop000:50070

  2. 停止hdfs
    sbin/stop-dfs.sh

HDFS关键设置及常见问题

常用配置

1
2
3
4
配置文件路径:$HADOOP_HOME$/etc/hadoop
主要配置文件:
•hdfs-site.xml
•core-site.xml

常见问题

小文件问题

  • 定义:大量大小小于块大小的文件
  • 实际场景:网页,Hive动态分区插入数据等
  • 背景:每个文件的元数据对象约占150byte,所以如果有1千万个小文件,每个文件占用一个block,则NameNode大约需要2G空间。如果存储1亿个文件,则NameNode需要20G空间;数据以块为单位进行处理。
  • 影响:占用资源,降低处理效率
  • 解决方案:
    • 从源头减少小文件
    • 使用archive打包
    • 使用其他存储方式,如Hbase、ES存储网页类型文件,使用spark等给hive分区数据重新合并切割。

Namenode内存管理

大数据量下的namenode问题:

  1. 启动时间变长
  2. 性能开始下降
  3. NameNode JVM FGC风险较高

解决方案:

  1. 根据数据增长情况,预估namenode内存需求,提前做好预案
  2. 使用HDFS Federation,扩展NameNode分散单点负载
  3. 引入外部系统支持NameNode内存数据
  4. 合并小文件(有相关的命令:hadoop archive)
  5. 调整合适的BlockSize

内存结构

内存预估
文件元数据对象约占200byte,block元数据约占180byte:
总内存 =198 * num(Directory + Files) + 176 * num(blocks) + 2% * 总内存

数据迁移

场景:

  • 冷热数据迁移
  • 集群升级、维护

方案:

  • hadoop distcp 命令

数据平衡

原因:长期运行的集群增删节点,节点增删磁盘等

影响:

  • 跨节点拷贝数据
  • task会存在任务失败的风险
  • 磁盘利用不均

方案:

  • 集群节点间:hdfs balancer 命令
  • 单节点磁盘间:hdfs diskbalancer 命令

hdfs balancer

参数:

  • -threshold 30 :判断集群是否平衡的目标参数,每一个 datanode
    存储使用率和集群总存储使用率的差值的绝对值都应该小于这个阀

  • dfs.datanode.balance.bandwidthPerSec 30m 传输的时候带宽30M

  • crontab job 每天凌晨20分调度
    [hadoop@hadoop001 sbin]$ ./start-balancer.sh -threshold 5

  • 一个DN节点的多个磁盘的数据均衡
    https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSDiskbalancer.html
    1、dfs.disk.balancer.enabled must be set to true in hdfs-site.xml.
    2、hdfs diskbalancer -plan 执行计划 生成xxx.plan.json
    3、hdfs diskbalancer -execute 执行计划.plan.json 执行
    4、hdfs diskbalancer -query 执行计划 查询状态

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    整体空间占用:30%
    threshold: 10
    balance之后每个dn的空间占用:20-40%

    dn1:60% ;dn2:10%;dn3:30%
    整体:
    dn1:40% ;dn2:30%;dn3:30%

    什么时候手动或调度执行?
    a.新盘加入
    b.监控服务器的磁盘剩余空间 小于阈值 10%,发邮件预警 手动执行
    配置多磁盘参数 dfs.datanode.data.dir /data01,/data02,/data03,/data04 comma-delimited(逗号)
  • -include :执行balance的DN列表

  • dfs.balance.balance.bandwidthPerSec 300MB :balance工具在运行中所能占用的带宽,设置的过大会影响其他任务

建议:

  • 对于一些大型的HDFS集群(随时可能扩容或下架服务器),balance脚本建议作为后台常驻进程
  • 根据官方建议,脚本需要部署在相对空闲的服务器上
  • 停止脚本通过kill进程实现

其他管理命令

  • hdfs dfsadmin
  • hdfs fsck

如何提高数据存取效率

数据压缩-作用

  • 节省数据占用的磁盘空间
  • 加快数据在磁盘和网络中的传输速度,从而提高系统的处理速度

数据压缩-评价指标

  • 压缩比:压缩比越高,压缩后文件越小,所以压缩比越高越好
  • 压缩时间:越快越好
  • 已经压缩的格式文件是否可以再分割:可以分割的格式允许单一文件由多个Mapper程序处理,可以更好的并行化

数据压缩-类型

压缩格式 工具 算法 扩展名 codec类 多文件 splitable native hadoop自带 Hadoop编解码
deflate deflate .deflate DeflateCodec org.apache.hadoop.io.compress.DeflateCodec
gzip gzip deflate .gz GzipCodec org.apache.hadoop.io.compress.GzipCodec
bzip2 bzip2 bzip2 .bz2 Bzip2Codec org.apache.hadoop.io.compress.Bzip2Codec
lzo lzop lzo .lzo LzopCodec 是[ifIndex] com.hadoop.compression.lzo.LzoCodec
lz4 lz4 .lz4 Lz4Codec org.apache.hadoop.io.compress.Lz4Codec
Snappy Snappy .snappy SnappyCodec org.apache.hadoop.io.compress.SnappyCodec

数据压缩-使用场景?

  • HDFS命令行写入:将数据压缩后写入
  • Flume写入:写入时指定hdfs.codeC参数
  • Sqoop写入:写入时指定参数
  • -compression-codec org.apache.hadoop.io.compress.SnappyCodec
  • HBase 数据存储: 创建表时指定
    create ‘xx_table’, {NAME => ‘xx_cf’, COMPRESSION => ‘GZ’}
  • Mapreduce中间结果和最终结果:hadoop jar xxx “-Dmapred.compress.map.output=true”
    “-Dmapred.map.output.compression.codec=xxx”
    “-Dmapred.output.compress=true” “-Dmapred.output.compression.codec=xxx”
  • Hive中间结果和最终结果:
    set hive.exec.compress.intermediate=true
    set mapred.map.output.compression.codec=xxx
    set mapred.map.output.compression.codec=xxx
    set hive.exec.compress.output=true
    set mapred.output.compression.codec=xxx
  • Spark(RDD分区、广播变量、shuffle输出):
    • rdd:spark.rdd.compress,是否压缩已序列化的rdd,默认关闭
    • broadcast:spark.broadcast.compress,是否压缩broadcast数据,默认打开
    • 结果存储:saveAsTextFile(path,codec)
    • 压缩算法:spark.io.compression.codec,默认为snappy

使用建议

  • 选择何种压缩格式:
    • 考虑是否支持切分
    • 压缩率vs压缩速度
  • 什么时候使用:
    • 存储:磁盘空间紧张
    • 计算:性能调优(内存空间占用,IO传输)

纠删码(hadoop3.0之后的功能)

复制策略:1tb的数据需要3tb的磁盘空间。
纠删码:只需要复制策略50%的磁盘空间,而且同样可以保存数据的可靠性。

原理解释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
X1=1
X2=2
X3=3
X1+X2+X3=6
X1+2*X2+3*X3=14
X1+3*X2+4*X3=14

我们需要求出X1,X2,X3的值,那么我们最少需要的方程是? 3
如果有四个方程,允许其中丢失任意一个方程

X1=1
X2=2
X3=3
视为我们的数据

X1+X2+X3=6
X1+2*X2+3*X3=14
X1+3*X2+4*X3=14
视为一个校验/冗余数据

如果是复制策略:要允许任意2份数据丢失,我们需要:3*3=9份数据。恢复的时候只需要找到相同的block直接复制就可以。
如果是纠删码策略:要允许任意2份数据丢失,我们需要:3+2=5份数据,时间换空间的策略。恢复的时候需要的时间大;因为各个block都要参与进来。

一个文件有n个块,最少需要的数据块数是多少?n+2;
不是针对一个文件所有的block块进行纠删码的计算,而是按照一定的size切分成block group,按照block group来计算冗余块。(平衡减少时间)

相关命令

1
2
3
4
5
6
7
8
9
10
11
hdfs ec [COMMAND]
[-listPolicies]
[-addPolicies -policyFile <file>]
[-getPolicy -path <path>]
[-removePolicy -policy <policy>]
[-setPolicy -path <path> [-policy <policy>] [-replicate]]
[-unsetPolicy -path <path>]
[-listCodecs]
[-enablePolicy -policy <policy>]
[-disablePolicy -policy <policy>]
[-help <command-name>]

使用建议

将冷门数据以纠删码格式转存,减少空间占用:

  1. 指定某个目录为纠删码模式:
    hdfs ec -setPolicy -path [path] -policy [policy]
  2. 通过distcp命令将原有数据转存

异构存储

  1. 配置dn存储路径时指定存储格式:
    [SSD]file:///path,[ARCHIVE]file:///path
  2. dn通过心跳汇报自身数据存储目录的StorageType给nn
  3. nn汇总并更新集群内各个节点的存储类型情况
  4. 客户端写入时根据设定的存储策略向nn请求响应的dn作为候
    选节点

相关命令

1
2
3
4
5
6
7
• hdfs storagepolicies [COMMAND]
[-listPolicies]
[-setStoragePolicy -path <path> -policy <policy>]
[-getStoragePolicy -path <path>]
[-unsetStoragePolicy -path <path>]
[-help <command-name>]
• hdfs mover [-p <files/dirs> | -f <local file>]

使用建议

  • 一般使用默认策略(HOT,磁盘)即可
  • ARCHIVE:计算能力较弱,存储密度高,存储冷数据
  • SSD:土豪专用